// LoopNode.java
package org.zjx.core.nodes;

import lombok.Getter;
import org.zjx.core.DecisionContext;
import org.zjx.core.DecisionNode;
import org.zjx.core.GameAction;

import java.util.function.Predicate;

/**
 * 循环执行节点
 *
 * 这个类实现了一个循环执行节点，允许在决策树中重复执行某个子节点，直到满足特定条件或达到最大迭代次数。
 */
@Getter
public class LoopNode implements DecisionNode {
    // 循环体节点，表示每次循环要执行的决策节点
    private final DecisionNode body;
    // 条件判断函数，用于判断是否继续循环
    private final Predicate<DecisionContext> condition;
    // 最大迭代次数，防止无限循环
    private final int maxIterations;

    /**
     * 构造函数（默认最大迭代次数为1000）
     *
     * @param body 循环体节点
     * @param condition 条件判断函数
     */
    public LoopNode(DecisionNode body, Predicate<DecisionContext> condition) {
        this(body, condition, 1000);
    }

    /**
     * 构造函数
     *
     * @param body 循环体节点
     * @param condition 条件判断函数
     * @param maxIterations 最大迭代次数
     */
    public LoopNode(DecisionNode body, Predicate<DecisionContext> condition, int maxIterations) {
        this.body = body;
        this.condition = condition;
        this.maxIterations = maxIterations;
    }

    /**
     * 决策方法
     *
     * 在决策过程中，根据条件判断是否继续循环执行子节点。
     * 如果子节点返回非null的GameAction，则直接返回该Action。
     *
     * @param context 决策上下文，包含当前状态和调用栈等信息
     * @return 返回的GameAction，如果子节点返回非null则直接返回，否则返回null
     */
    @Override
    public GameAction decide(DecisionContext context) {
        int count = 0;
        // 循环执行，直到条件不满足或达到最大迭代次数
        while (condition.test(context) && count++ < maxIterations) {
            // 执行循环体节点，获取返回的GameAction
            GameAction action = body.decide(context);
            // 如果子节点返回非null的GameAction，则直接返回
            if (action != null) {
                return action;
            }
        }
        // 循环结束，返回null
        return null;
    }
}